<template>
  <div class="chunk-uploader" :class="{ 'has-video': modelValue }">
    <!-- 左侧视频预览区 -->
    <div v-if="modelValue" class="preview-section">
      <div class="preview-wrapper">
        <video
            :src="modelValue"
            controls
            muted
            class="video-preview"
            @click.stop
        ></video>
      </div>
    </div>

    <!-- 右侧上传交互区 -->
    <div
        class="upload-section"
        :class="{ 'dragover': isDragging }"
        @dragover.prevent="handleDragOver"
        @dragleave.prevent="isDragging = false"
        @drop.prevent="handleDrop"
    >
      <div
          class="upload-container"
          @click="triggerUpload"
      >
        <transition name="el-fade-in">
          <div v-if="!modelValue" class="upload-guide">
            <el-icon class="upload-icon"><UploadFilled /></el-icon>
            <div class="upload-text">
              <p>点击上传或拖拽视频到此区域</p>
              <p class="tip">支持断点续传，最大{{ formattedMaxSize }}</p>
            </div>
          </div>
        </transition>

        <div v-if="modelValue" class="reupload-guide">
          <el-icon class="refresh-icon"><Refresh /></el-icon>
          <p class="reupload-text">点击上传新视频替换当前内容</p>
        </div>

        <div v-if="progress > 0" class="progress-container">
          <el-progress
              :percentage="progress"
              :status="statusMap[uploadStatus]"
              :stroke-width="16"
              :format="progressFormat"
          />
          <div class="status-info">
            <el-icon v-if="uploadStatus === 'success'" color="#67C23A"><CircleCheckFilled /></el-icon>
            <el-icon v-else-if="uploadStatus === 'error'" color="#F56C6C"><CircleCloseFilled /></el-icon>
            <span>{{ statusText }}</span>
          </div>
        </div>
      </div>
    </div>

    <input
        ref="fileInput"
        type="file"
        :accept="fileType"
        @change="handleFileChange"
        style="display: none"
    />
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { chunkUpload } from '../service/minioFileApi'
import {
  CircleCheckFilled,
  CircleCloseFilled,
  UploadFilled,
  Warning,
  Refresh
} from '@element-plus/icons-vue'

const props = defineProps({
  modelValue: String,
  fileType: {
    type: String,
    default: 'video/*'
  },
  maxSize: {
    type: Number,
    default: 2 * 1024 * 1024 * 1024
  },
  isEditMode: Boolean
})

const emit = defineEmits(['update:modelValue', 'success', 'error'])

// 响应式状态
const fileInput = ref(null)
const isDragging = ref(false)
const uploading = ref(false)
const progress = ref(0)
const uploadStatus = ref('')
const statusText = ref('')

const statusMap = {
  uploading: '',
  success: 'success',
  error: 'exception'
}

// 计算属性
const formattedMaxSize = computed(() => {
  const sizeInGB = props.maxSize / (1024 ** 3)
  return `${sizeInGB}GB`
})

// 核心上传逻辑
const handleFileUpload = async (file) => {
  try {
    uploading.value = true
    uploadStatus.value = 'uploading'
    statusText.value = '校验文件中...'

    const finalUrl = await chunkUpload(file, {
      chunkSize: 10 * 1024 * 1024,
      parallel: 3
    }, (percent) => {
      progress.value = percent
      statusText.value = percent < 100 ? `上传中 ${percent}%` : '文件合并中...'
    })

    emit('update:modelValue', finalUrl)
    emit('success', finalUrl)
    uploadStatus.value = 'success'
    statusText.value = '上传成功'

  } catch (err) {
    uploadStatus.value = 'error'
    statusText.value = err.response?.data?.message || err.message
    emit('error', err)
    ElMessage.error(`上传失败：${statusText.value}`)
  } finally {
    uploading.value = false
    setTimeout(() => {
      if(uploadStatus.value === 'success') {
        progress.value = 0
        statusText.value = ''
      }
    }, 3000)
  }
}

// 事件处理
const triggerUpload = () => {
  if (!uploading.value) fileInput.value.click()
}

const handleDragOver = (e) => {
  if (!uploading.value) isDragging.value = true
}

const handleDrop = (e) => {
  isDragging.value = false
  const file = e.dataTransfer.files[0]
  validateAndUpload(file)
}

const handleFileChange = (e) => {
  const file = e.target.files[0]
  validateAndUpload(file)
}

// 文件验证
const validateAndUpload = (file) => {
  if (!file) return

  if (!file.type.match(props.fileType.replace('*', '.*'))) {
    return ElMessage.error('不支持的文件格式')
  }

  if (file.size > props.maxSize) {
    return ElMessage.error(`文件大小超过${formattedMaxSize.value}限制`)
  }

  handleFileUpload(file)
}

// 暴露方法
defineExpose({
  reset: () => {
    fileInput.value.value = ''
    progress.value = 0
    uploadStatus.value = ''
    statusText.value = ''
  }
})

// 进度格式化
const progressFormat = (p) => {
  switch(uploadStatus.value) {
    case 'success': return '上传完成'
    case 'error': return '上传失败'
    default: return `${p}%`
  }
}
</script>

<style scoped>
.chunk-uploader {
  display: flex;
  gap: 20px;
  min-height: 240px;

&.has-video {
.preview-section {
  flex: 0 0 55%;
  max-width: 600px;
}
.upload-section {
  flex: 1;
}
}

&:not(.has-video) {
.upload-section {
  width: 100%;
  margin: 0 auto;
}
}
}

.preview-section {
  position: relative;
  border-radius: 8px;
  overflow: hidden;
  background: #000;

.preview-wrapper {
  height: 100%;
  position: relative;

.video-preview {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.replace-tip {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 12px;
  background: rgba(255, 186, 0, 0.9);
  color: #fff;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
}
}

.upload-section {
  border: 2px dashed var(--el-border-color);
  border-radius: 8px;
  transition: all 0.3s;
  padding: 20px;
  display: flex;
  align-items: center;
  justify-content: center;

&.dragover {
   border-color: var(--el-color-primary);
   background: rgba(64, 158, 255, 0.08);
 }

.upload-container {
  width: 100%;
  max-width: 400px;
  text-align: center;

.upload-guide {
.upload-icon {
  font-size: 48px;
  color: var(--el-text-color-secondary);
  margin-bottom: 16px;
}

.tip {
  font-size: 12px;
  color: var(--el-text-color-placeholder);
}
}

.reupload-guide {
  cursor: pointer;
  padding: 20px;
  border-radius: 8px;
  transition: background 0.2s;

&:hover {
   background: var(--el-fill-color-light);

.refresh-icon {
  color: var(--el-color-primary);
}
}

.refresh-icon {
  font-size: 40px;
  margin-bottom: 12px;
  transition: color 0.2s;
}

.reupload-text {
  color: var(--el-text-color-secondary);
}
}

.progress-container {
  margin-top: 24px;

.status-info {
  margin-top: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 14px;
}
}
}
}

@media (max-width: 768px) {
  .chunk-uploader {
    flex-direction: column;

&.has-video {
  .preview-section {
    flex: none;
    height: 200px;
  }
}
}
}
</style>
